package ui;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.FontUIResource;

import entity.Event;
import entity.ICalendar;

/**
 * The main panel of the ICalendar Generator.
 * 
 * @author Sean Young
 * @version 1.0
 *
 */
public class CalendarUI extends JPanel{
	private MenuBar menuBar;
	private JPanel cardPanel;
	private CreateEventPanel createEventPanel;
	private CreateCalendar createCalendarPanel;
	private CalendarPanel calendarPanel;
	private ArrayList<ICalendar> calendars;
	private Event currentEvent;
	private JFileChooser fc;
	
	/**
	 * Constructor for the CalendarUI main panel.
	 */
	public CalendarUI(){
		super(new BorderLayout());
		setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		
		fc = new JFileChooser();
		fc.setDialogTitle("Export to");
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fc.setAcceptAllFileFilterUsed(false);
		
		calendars = new ArrayList<ICalendar>();
		ICalendar ical = new ICalendar("iCalTest");
		ical.setVersion("2.0");
		calendars.add(ical);
		
		createEventPanel = new CreateEventPanel(this);
		calendarPanel = new CalendarPanel(this);
		createCalendarPanel = new CreateCalendar(this);
		menuBar = new MenuBar(this);
		
		cardPanel = new JPanel(new CardLayout());
		cardPanel.add(createCalendarPanel, "Create Calendar Panel");
		cardPanel.add(createEventPanel, "Create Event Panel");
		
		this.add(cardPanel, BorderLayout.CENTER);
		this.add(calendarPanel, BorderLayout.NORTH);
		
	}
	
	/**
	 * Changes the panel to either the Create Event Panel or
	 * the Create Calendar Panel based upon the name specified
	 * as the parameter
	 * @param name The name of the panel
	 */
	public void changePanel(String name) {
		CardLayout cardLayout = (CardLayout) (cardPanel.getLayout());
		if(name.equals("Create Event Panel"))
		{ 
			createEventPanel.reset();
			cardLayout.show(cardPanel, name);
		} else if (name.equals("Create Calendar Panel")) {
			cardLayout.show(cardPanel, name);
		}
	}
	
	/**
	 * Refreshes the CalendarPanel
	 */
	public void refreshCalPanel() {
		calendarPanel.refresh();
	}
	
	/**
	 * Returns an ArrayList of all the ICalendars
	 * @return ArrayList of all ICalendars
	 */
	public ArrayList<ICalendar> getCalendars() {
		return calendars;
	}
	
	/**
	 * Exits the program.
	 */
	public void exit() {
		System.exit(0);
	}
	
	/**
	 * Exports the currently selected ICalendar to the current directory.
	 */
	public void export() {
		try{
			String fileName = calendars.get(calendarPanel.getSelectedIndex()).getName() + ".ics";
			File file = new File(fileName);
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
			out.write(calendars.get(calendarPanel.getSelectedIndex()).toString());
			out.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Exports the currently selected ICalendar to the directory selected through
	 * the JFileChooser.
	 */
	public void exportPath() {
		try{
			String exportPathStr = findExportPath();
			if(exportPathStr.equals("")) return;
			
			String fileName = calendars.get(calendarPanel.getSelectedIndex()).getName() + ".ics";
			File exportPath = new File(exportPathStr, fileName);
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(exportPath), "UTF-8"));
			out.write(calendars.get(calendarPanel.getSelectedIndex()).toString());
			out.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Allows the user to select a path to export to and then
	 * returns the selected path as a String. An empty string
	 * will be returned if the user does not select a path 
	 * or selects and invalid path.
	 * @return A string containing the export path
	 */
	public String findExportPath() {
		int returnVal = fc.showSaveDialog(CalendarUI.this);
		if(returnVal == JFileChooser.APPROVE_OPTION) {
			File tempExportPath = fc.getSelectedFile();
			return tempExportPath.toString();
		}
		else return "";
	}
	
	/**
	 * Generates the UI to be run in the main method.
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws UnsupportedLookAndFeelException
	 */
	public static void createAndShowUI() throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException{
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
		JFrame frame = new JFrame();
		frame.setTitle("ICalendar File Generator");
		CalendarUI ui = new CalendarUI();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(new Dimension(450, 375));
		ImageIcon icon = new ImageIcon("images/Calendar-3-256x256.png");
		frame.setIconImage(icon.getImage());
		frame.setResizable(false);
		frame.add(ui);
		frame.setJMenuBar(ui.menuBar);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
	/**
	 * Adds the specified event to the currently selected Calendar.
	 * @param e The event to add to the Calendar
	 */
	public void addEvent(Event e) {
		calendars.get(calendarPanel.getSelectedIndex()).addEvent(e);
	}
	
	/**
	 * Adds an ICalendar to the list of ICalendars
	 * @param cal The Calendar to add to the ArrayList of calendars
	 */
	public void addCalendar(ICalendar cal) {
		calendars.add(cal);
	}
	
	/**
	 * Adjusts the font for the entire UI.
	 * @param f The font that all text will be set to.
	 */
	public static void setUIFont(FontUIResource f) {
        Enumeration keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource) {
                FontUIResource orig = (FontUIResource) value;
                Font font = new Font(f.getFontName(), orig.getStyle(), f.getSize());
                UIManager.put(key, new FontUIResource(font));
            }
        }
	}
	
	public static void main(String[] args) {
		try {
			//setUIFont(new FontUIResource(new Font("Calbri", 0, 16)));
			createAndShowUI();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error: unable to start program.");
		}

	}
}
